package com.yzd.netmonitor.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

//destroy----bean销毁---destroy方法
@Component("httpRequestUtils")
@Lazy(false)
public class HttpRequestUtils implements DisposableBean {

	private static final Logger logger = LoggerFactory.getLogger(HttpRequestUtils.class);

	//用于从客户端发送HTTP请求到服务器端
	private static CloseableHttpClient httpclient;

	private static int threadSize = 10;

	static {
		//管理CloseableHttpClient的
		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
		cm.setMaxTotal(threadSize);
		//HttpClient可以通过多个执行线程同时执行多个请求
		httpclient = HttpClients.custom().setConnectionManager(cm).build();
	}

	public static String post(String url, Map<String, String> headers, Map<String, String> params,
			int timeout) {

		try {
			//将要请求的URL通过构造方法传入HttpPost对象
			HttpPost post = new HttpPost(url);

			/**
			 * 获取和配置一些外部的网络环境
			 * custom()获取equestConfig.Builder“配置器”
			 * 再调用配置器的build()方法返回RequestConfig对象
			 */
			RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout * 1000)
					.setSocketTimeout(timeout * 1000).build();
			post.setConfig(config);

			if (MapUtils.isNotEmpty(headers)) {
				Set<Entry<String, String>> items = headers.entrySet();
				for (Entry<String, String> item : items) {
					//设置post请求头
					post.setHeader(item.getKey(), item.getValue());
				}
			}

			/**
			 * httpClient参数 request response
			 * params 有用参数
			 */
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			if (MapUtils.isNotEmpty(params)) {
				Set<Entry<String, String>> items = params.entrySet();
				for (Entry<String, String> item : items) {
					nvps.add(new BasicNameValuePair(item.getKey(), item.getValue()));
				}
			}
			post.setEntity(new UrlEncodedFormEntity(nvps));
			try (
				//execute(HttpUriRequest request)发送请求，该方法返回一个HttpResponse
				CloseableHttpResponse response = httpclient.execute(post)
			) {
				//该对象包装了服务器的响应内容（服务器页面body体之内的内容），不包含响应头
				HttpEntity respEntity = response.getEntity();
				if (respEntity != null) {
					//将从服务器中获取到所有内容放到inputstream对象中
					InputStream instream = respEntity.getContent();
					String resultStr = IOUtils.toString(instream, "UTF-8");
					logger.info("response resultStr by text:" + resultStr);
					return resultStr;
				}
				//关闭HttpEntity中的流
				EntityUtils.consume(respEntity);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return null;
	}

	public static String get(String url, Map<String, String> headers, int timeout) {

		try {
			HttpGet get = new HttpGet(url);

			RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout * 1000)
					.setSocketTimeout(timeout * 1000).build();

			get.setConfig(config);

			if (MapUtils.isNotEmpty(headers)) {
				Set<Entry<String, String>> items = headers.entrySet();
				for (Entry<String, String> item : items) {
					get.setHeader(item.getKey(), item.getValue());
				}
			}

			try (CloseableHttpResponse response = httpclient.execute(get)) {
				HttpEntity respEntity = response.getEntity();
				if (respEntity != null) {
					InputStream instream = respEntity.getContent();
					String resultStr = IOUtils.toString(instream, "UTF-8");
					logger.info("response resultStr by text:" + resultStr);
					return resultStr;
				}
				EntityUtils.consume(respEntity);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return null;
	}

	@Override
	public void destroy() throws Exception {

		httpclient.close();
	}

}
